# Create your views here.
from django.db import connection
from rest_framework.decorators import api_view, authentication_classes
import numpy as np 
from myapp import utils
from myapp.handler import APIResponse
from myapp.models import Classification, Thing, Tag, User,ThingCollection,Comment
from myapp.serializers import ThingSerializer, ClassificationSerializer, ListThingSerializer, DetailThingSerializer
from myapp.utils import dict_fetchall
import jieba 

from collections import Counter


def recommend(username):
    # 获取用户的收藏列表
    user = User.objects.get(username=username)
    user_id = user.id
    # get all things 
    things = Thing.objects.all()
    things_ids = [(idx,thing.id) for idx,thing in enumerate(things)]
    # get all user's collect
    target_collect = ThingCollection.objects.filter(user_id=user_id)
    target_collect = set([(item.user_id,item.thing_id) for item in target_collect])
    all_collect = ThingCollection.objects.exclude(user_id=user_id)
    all_collect = set([(item.user_id,item.thing_id) for item in all_collect])
    usrs = list(set([item[0] for item in all_collect]))
    matrix = np.zeros((len(usrs),len(things_ids)))
    for i in range(len(usrs)):
        for j in range(len(things_ids)):
            if (usrs[i],things_ids[j][1]) in all_collect:
                matrix[i,j] = 1

    target_vec = np.zeros(len(things_ids))
    for i in range(len(things_ids)):
        if (user_id,things_ids[i][1]) in target_collect:
            target_vec[i] = 1
    # 计算用户相似度
    sims = []
    print(usrs)
    for i in range(len(usrs)):
        sim = np.dot(matrix[i],target_vec)/(np.linalg.norm(matrix[i])*np.linalg.norm(target_vec))
        sims.append(sim)
    sims = np.array(sims)
    print(sims)
    # 获取相似度最高的用户
    max_sim = np.max(sims)
    max_sim_idx = np.argmax(sims)
    # 获取相似度最高的用户的收藏列表
    max_sim_collect = ThingCollection.objects.filter(user_id=usrs[max_sim_idx])
    rec_things_ids = [item.thing_id for item in max_sim_collect]
    rec_things = Thing.objects.filter(id__in=rec_things_ids)
    serializer = ListThingSerializer(rec_things, many=True)
    print(serializer.data)
    return APIResponse(code=0, msg='查询成功', data=serializer.data)




@api_view(['GET'])
def list_api(request):
    if request.method == 'GET':
        keyword = request.GET.get("keyword", None)
        c = request.GET.get("c", None)
        tag = request.GET.get("tag", None)
        sort = request.GET.get("sort", 'recent')

        # 排序方式
        order = '-create_time'
        if sort == 'recent':
            order = '-create_time'
        elif sort == 'hot' :
            order = '-pv'
        elif sort == 'recommend':
            username = request.GET.get('username', None)
            return recommend(username)
        if keyword:
            things = Thing.objects.filter(title__contains=keyword).order_by(order)

        # todo
        elif c and int(c) > -1:
            ids = [c]

            things = Thing.objects.filter(classification_id__in=ids).order_by(order)

        elif tag:
            tag = Tag.objects.get(id=tag)
            print(tag)
            things = tag.thing_set.all().order_by(order)
        else:
            things = Thing.objects.all().order_by(order)

        serializer = ListThingSerializer(things, many=True)
        return APIResponse(code=0, msg='查询成功', data=serializer.data)


@api_view(['GET'])
def detail(request):
    try:
        pk = request.GET.get('id', -1)
        thing = Thing.objects.get(pk=pk)
    except Thing.DoesNotExist:
        utils.log_error(request, '对象不存在')
        return APIResponse(code=1, msg='对象不存在')

    if request.method == 'GET':
        serializer = ThingSerializer(thing)
        return APIResponse(code=0, msg='查询成功', data=serializer.data)


@api_view(['POST'])
def increaseWishCount(request):
    try:
        pk = request.GET.get('id', -1)
        thing = Thing.objects.get(pk=pk)
        # wish_count加1
        thing.wish_count = thing.wish_count + 1
        thing.save()
    except Thing.DoesNotExist:
        utils.log_error(request, '对象不存在')
        return APIResponse(code=1, msg='对象不存在')

    serializer = ThingSerializer(thing)
    return APIResponse(code=0, msg='操作成功', data=serializer.data)

@api_view(['POST'])
def increaseRecommendCount(request):
    try:
        pk = request.GET.get('id', -1)
        thing = Thing.objects.get(pk=pk)
        # recommend_count加1
        thing.recommend_count = thing.recommend_count + 1
        thing.save()
    except Thing.DoesNotExist:
        utils.log_error(request, '对象不存在')
        return APIResponse(code=1, msg='对象不存在')

    serializer = ThingSerializer(thing)
    return APIResponse(code=0, msg='操作成功', data=serializer.data)

@api_view(['POST'])
def addWishUser(request):
    try:
        username = request.GET.get('username', None)
        thingId = request.GET.get('thingId', None)

        if username and thingId:
            user = User.objects.get(username=username)
            thing = Thing.objects.get(pk=thingId)

            if user not in thing.wish.all():
                thing.wish.add(user)
                thing.wish_count += 1
                thing.save()

    except Thing.DoesNotExist:
        utils.log_error(request, '操作失败')
        return APIResponse(code=1, msg='操作失败')

    serializer = ThingSerializer(thing)
    return APIResponse(code=0, msg='操作成功', data=serializer.data)

@api_view(['POST'])
def removeWishUser(request):
    try:
        username = request.GET.get('username', None)
        thingId = request.GET.get('thingId', None)

        if username and thingId:
            user = User.objects.get(username=username)
            thing = Thing.objects.get(pk=thingId)

            if user in thing.wish.all():
                thing.wish.remove(user)
                thing.wish_count -= 1
                thing.save()

    except Thing.DoesNotExist:
        utils.log_error(request, '操作失败')
        return APIResponse(code=1, msg='操作失败')

    return APIResponse(code=0, msg='操作成功')

@api_view(['GET'])
def getWishThingList(request):
    try:
        username = request.GET.get('username', None)
        if username:
            user = User.objects.get(username=username)
            things = user.wish_things.all()
            serializer = ListThingSerializer(things, many=True)
            return APIResponse(code=0, msg='操作成功', data=serializer.data)
        else:
            return APIResponse(code=1, msg='username不能为空')

    except Exception as e:
        utils.log_error(request, '操作失败' + str(e))
        return APIResponse(code=1, msg='获取心愿单失败')


@api_view(['POST'])
def addCollectUser(request):
    try:
        username = request.GET.get('username', None)
        thingId = request.GET.get('thingId', None)

        if username and thingId:
            user = User.objects.get(username=username)
            thing = Thing.objects.get(pk=thingId)

            if user not in thing.collect.all():
                thing.collect.add(user)
                thing.collect_count += 1
                thing.save()

    except Thing.DoesNotExist:
        utils.log_error(request, '操作失败')
        return APIResponse(code=1, msg='操作失败')

    serializer = DetailThingSerializer(thing)
    return APIResponse(code=0, msg='操作成功', data=serializer.data)


@api_view(['POST'])
def removeCollectUser(request):
    try:
        username = request.GET.get('username', None)
        thingId = request.GET.get('thingId', None)

        if username and thingId:
            user = User.objects.get(username=username)
            thing = Thing.objects.get(pk=thingId)
            user_id = user.id
            thing_id = thing.id

            thingcollection = ThingCollection.objects.filter(user_id=user_id, thing_id=thing_id)
            thingcollection.delete()

    except Thing.DoesNotExist:
        utils.log_error(request, '操作失败')
        return APIResponse(code=1, msg='操作失败')

    return APIResponse(code=0, msg='操作成功')


@api_view(['GET'])
def getCollectThingList(request):
    try:
        username = request.GET.get('username', None)
        if username:
            user = User.objects.get(username=username)
            user_id = user.id
            things = ThingCollection.objects.filter(user_id=user_id)
            things_ids = [thing.thing_id for thing in things]
            things = Thing.objects.filter(id__in=things_ids)
            serializer = ListThingSerializer(things, many=True)
            return APIResponse(code=0, msg='操作成功', data=serializer.data)
        else:
            return APIResponse(code=1, msg='username不能为空')

    except Exception as e:
        utils.log_error(request, '操作失败' + str(e))
        return APIResponse(code=1, msg='获取收藏失败')




@api_view(['POST'])
def postThingCollect(request):
    try:
        username = request.GET.get('user_id', None)
        thing_id = request.GET.get('thing_id', None)
        print(username, thing_id)
        if username and thing_id:
            thingcollection = ThingCollection.objects.create(user_id=username, thing_id=thing_id)
            thingcollection.save()
            return APIResponse(code=0, msg='收藏成功')
        else:
            return APIResponse(code=1, msg='参数错误')
    except Exception as e:
        print(e)
        utils.log_error(request, '操作失败' + str(e))
        return APIResponse(code=1, msg='收藏失败')
    
            
@api_view(['GET'])
def getStaticData(request):
    try:
        response = {
            'user_count': User.objects.count(),
            'thing_count': Thing.objects.count(),
            'thing_status_0_count': Thing.objects.filter(status=0).count(), 
            'thing_status_1_count': Thing.objects.filter(status=1).count(),
            'comment_count': Comment.objects.count(),
            'collection_count': ThingCollection.objects.count(),
        }
        commets = Comment.objects.all()
        for comment in commets:
            comment.comment_time = comment.comment_time.strftime('%Y-%m-%d')
        comment_daily_incr = [item.comment_time for item in commets]
        comment_daily_incr = dict(Counter(comment_daily_incr))
        comment_daily = [{'date': key, 'count': value} for key, value in comment_daily_incr.items()]
        content = [item.content for item in commets]    
        content = ' '.join(content)
        word_list = jieba.cut(content, cut_all=True)
        word = Counter(word_list)
        word = dict(word)
        word = [{'word': key, 'count': value} for key, value in word.items()]
        response['word'] = word
        users = User.objects.all()
        # 用户按照create time 计数 create_time为天
        for user in users:
            user.create_time = user.create_time.strftime('%Y-%m-%d')
        daily_incr = [item.create_time for item in users]
        daily_incr = dict(Counter(daily_incr))
        daily = [{'date': key, 'count': value} for key, value in daily_incr.items()]
        response['user'] = daily
        response['comment_daily'] = comment_daily
        return APIResponse(code=0, msg='查询成功', data=response)
    except Exception as e:
        print(e)
        utils.log_error(request, '操作失败' + str(e))
        return APIResponse(code=1, msg='查询失败')

        
